package com.jvtd.zego;

import android.app.Application;
import android.content.Context;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.zego.zegoliveroom.ZegoLiveRoom;
import com.zego.zegoliveroom.constants.ZegoAvConfig;
import com.zego.zegoliveroom.constants.ZegoConstants;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class JvtdZego {
    private static volatile JvtdZego instance;
    private long mAppId;
    private byte[] mAppKey;
    private Application mApplication;
    private Context mContext;

    private ZegoLiveRoom mZegoLiveRoom = null;
    private ZegoAvConfig zegoAvConfig;

    //竖屏
    public static final int ZEGO_ROTATION_0 = 1;
    //横屏
    public static final int ZEGO_ROTATION_270 = 0;

    @IntDef({ZEGO_ROTATION_0, ZEGO_ROTATION_270})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ScreenType {
    }

    private boolean isSdkContext = false;
    private boolean isUserInfo = false;

    private final int[][] VIDEO_RESOLUTIONS = new int[][]{{320, 240}, {352, 288}, {640, 360},
            {960, 540}, {1280, 720}, {1920, 1080}};

    public static JvtdZego getInstance() {
        if (instance == null)
            synchronized (JvtdZego.class) {
                if (instance == null)
                    instance = new JvtdZego();
            }
        return instance;
    }

    private JvtdZego() {
        mZegoLiveRoom = new ZegoLiveRoom();
    }

    //初始化既构相关参数
    public JvtdZego init(long appId, byte[] appKey, Application application) {
        this.mAppId = appId;
        this.mAppKey = appKey;
        this.mApplication = application;
        this.mContext = application.getApplicationContext();
        return this;
    }

    public ZegoLiveRoom getLiveRoom() {
        return mZegoLiveRoom;
    }

    //开发模式
    public JvtdZego isDevelopment(boolean enabled) {
        ZegoLiveRoom.setTestEnv(enabled);
        return this;
    }

    //初始化sdkContext
    public JvtdZego initSdkContext() {
        return initSdkContext(new ZegoLiveRoom.SDKContextEx() {

            @Nullable
            @Override
            public String getSoFullPath() {
                return null;
            }

            @Nullable
            @Override
            public String getLogPath() {
                return null;
            }

            @NonNull
            @Override
            public Application getAppContext() {
                return mApplication;
            }

            @Override
            public long getLogFileSize() {
                return 10 * 1024 * 1024;
            }
        });
    }

    public JvtdZego initSdkContext(ZegoLiveRoom.SDKContextEx sdkContextEx) {
        isSdkContext = true;
        ZegoLiveRoom.setSDKContext(sdkContextEx);
        return this;
    }

    //初始化 用户信息
    public JvtdZego initUserInfo(String userId, String userName) {
        isUserInfo = true;
        ZegoLiveRoom.setUser(userId, userName);
        return this;
    }

    /**
     * 高级功能.
     */
    private void openAdvancedFunctions() {
        // 外部渲染
        if (JvtdZegoUtils.getInstance(mContext).getUseExternalRender(false)) {
            // 开启外部渲染
            ZegoLiveRoom.enableExternalRender(true);
        }
    }

    public JvtdZego open() {
        return open(true);
    }

    public JvtdZego open(boolean isConfig) {
        if (mAppId < 0 || mAppKey == null || mAppKey.length <= 0) {
            try {
                throw new Exception("请设置APP相关信息");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (!isUserInfo) {
            try {
                throw new Exception("请设置用户信息");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (!isSdkContext)
            initSdkContext();
        openAdvancedFunctions();
        // 初始化sdk
        if (mZegoLiveRoom == null)
            mZegoLiveRoom = new ZegoLiveRoom();
        boolean ret = mZegoLiveRoom.initSDK(mAppId, mAppKey);

        if (JvtdZegoUtils.getInstance(mContext).getAPPWebRtc()) {
            mZegoLiveRoom.setLatencyMode(ZegoConstants.LatencyMode.Low2);
        }

        if (!ret) {
            //初始化失败
            Toast.makeText(mContext, "Zego SDK初始化失败!", Toast.LENGTH_LONG).show();
        } else {
            int liveQualityLevel = JvtdZegoUtils.getInstance(mContext).getLiveQuality(3);
            switch (liveQualityLevel) {
                case 0:
                    zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.VeryLow);
                    break;
                case 1:
                    zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.Low);
                    break;
                case 2:
                    zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.Generic);
                    break;
                case 3:
                    zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.High);
                    break;
                case 4:
                    zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.VeryHigh);
                    break;
                case 5:
                    zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.SuperHigh);
                    break;
                case 6:
                    // 自定义设置
                    zegoAvConfig = initZegoAvConfig(ZEGO_ROTATION_0);
                    break;
            }

            if (isConfig) {
                mZegoLiveRoom.setAVConfig(zegoAvConfig);
            }

            // 硬件编码
            setUseHardwareEncode(JvtdZegoUtils.getInstance(mContext).getHardwareEncode(true));
            // 硬件解码
            setUseHardwareDecode(JvtdZegoUtils.getInstance(mContext).getHardwareDecode(true));
            // 码率控制
            setUseRateControl(JvtdZegoUtils.getInstance(mContext).getEnableRateControl(false));
        }
        return this;
    }

    //自定义avConfig
    public void setZegoConfig(ZegoAvConfig config) {
        zegoAvConfig = config;
        mZegoLiveRoom.setAVConfig(config);
    }

    /**
     * 刷新配置
     *
     * @param orientation 竖屏还是横屏
     */
    public void refreshZegoAvConfig(int orientation) {
        zegoAvConfig = initZegoAvConfig(orientation);
        mZegoLiveRoom.setAVConfig(zegoAvConfig);
    }

    public ZegoAvConfig initZegoAvConfig(int orientation) {
        int liveQualityLevel = JvtdZegoUtils.getInstance(mContext).getLiveQuality(3);
        //默认竖屏
        int number = 1;
        if (orientation == ZEGO_ROTATION_270) {
            //切换横屏
            number = 0;
        }
        zegoAvConfig = new ZegoAvConfig(ZegoAvConfig.Level.High);
        int progress = JvtdZegoUtils.getInstance(mContext).getVideoResolutions(0);
        if (liveQualityLevel != 6) {
            progress = liveQualityLevel;
        }
        int width = VIDEO_RESOLUTIONS[progress][number];
        int height = VIDEO_RESOLUTIONS[progress][number == 0 ? 1 : 0];
        Log.e("initZegoAvConfig", String.format("width: %d", width));
        Log.e("initZegoAvConfig", String.format("height: %d", height));
        zegoAvConfig.setVideoEncodeResolution(width, height);
        zegoAvConfig.setVideoCaptureResolution(width, height);
        int videoFps = JvtdZegoUtils.getInstance(mContext).getVideoFps(15);
        zegoAvConfig.setVideoFPS(videoFps);
        int videoBitrate = JvtdZegoUtils.getInstance(mContext).getVideoBitrate(0);
        zegoAvConfig.setVideoBitrate(videoBitrate);
        return zegoAvConfig;
    }

    public void setUseHardwareEncode(boolean useHardwareEncode) {
        if (useHardwareEncode) {
            // 开硬编时, 关闭码率控制
            if (JvtdZegoUtils.getInstance(mContext).getEnableRateControl(false)) {
                mZegoLiveRoom.enableRateControl(false);
                JvtdZegoUtils.getInstance(mContext).setEnableRateControl(false);
            }
        }
        ZegoLiveRoom.requireHardwareEncoder(useHardwareEncode);

        JvtdZegoUtils.getInstance(mContext).setRequireHardwareEncoder(useHardwareEncode);
    }

    public void setUseHardwareDecode(boolean useHardwareDecode) {
        ZegoLiveRoom.requireHardwareDecoder(useHardwareDecode);
        JvtdZegoUtils.getInstance(mContext).setRequireHardwareDecoder(useHardwareDecode);
    }

    public void setUseRateControl(boolean useRateControl) {
        if (useRateControl) {
            // 开码率控制时, 关硬编
            if (JvtdZegoUtils.getInstance(mContext).getHardwareEncode(true)) {
                ZegoLiveRoom.requireHardwareEncoder(false);
                JvtdZegoUtils.getInstance(mContext).setRequireHardwareEncoder(false);
            }
        }
        JvtdZegoUtils.getInstance(mContext).setEnableRateControl(useRateControl);
        mZegoLiveRoom.enableRateControl(useRateControl);
    }

    public void releaseSDK() {
        // 清空高级设置
        ZegoLiveRoom.setTestEnv(false);
        ZegoLiveRoom.enableExternalRender(false);
        mZegoLiveRoom.unInitSDK();
    }
}
